package beanstao.util.id;

import java.io.Serializable;
import java.util.UUID;

import beanstao.util.Strings;
import beanstao.util.exception.technical.dal.domain.DomainSetException;
import beanstao.util.log.ILog;
import beanstao.util.log.LogHelper;

/**
 * 针对 DomainObject 类型的实体的ID的封装。实现校验与可配置。<br>
 * 鉴于太常用，本类型的命名针对(DomainObject Id)使用了缩写。<br>
 * 一般使用可以以 Id.Me("idstring") 的方式。<br>
 * <b>本类型的ID一般会采用GUID，以保证全局的唯一性。</b>
 * 
 * @author beanstao@google.com 
 */
public class DId implements Serializable, Id, ILog
{
	private static final long serialVersionUID = -2712834491071827602L;

	/**
	 * @return 创建一个新的ID
	 */
	public static Id ME()
	{
		UUID uuid = UUID.randomUUID();
		return new DId(uuid.toString());
	}

	/**
	 * 解析一个ID字符串(一般为一个GUID)
	 * 
	 * @param id
	 * @return
	 */
	public static Id ME(String id)
	{
		return new DId(id);
	}

	protected DId(String id)
	{
		if (Strings.isEmpty(id))
			throw new IllegalArgumentException(this.getClass() + " >>> ID字符串为空。");
		_Id = id;
		if (!this.validate())
			throw new DomainSetException();
	}

	private String _Id = "";

	public String getId()
	{
		return _Id;
	}

	private IdSetting _Setting = new IdSetting(DomainIdType.GUID);

	public void setSetting(IdSetting _Setting)
	{
		this._Setting = _Setting;
	}

	public IdSetting getSetting()
	{
		return _Setting;
	}

	protected boolean validate()
	{
		return true;
		// TODO: DomainId的校验暂时未做。 
	}

	@Override
	public String toString()
	{
		return this.getId();
	}

	@Override
	public String toXPath()
	{
		return String.format("//%s[@%s='%s']", "%s", "id", _Id);
	}

	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + ((_Id == null) ? 0 : _Id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj)
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (this.getClass() != obj.getClass())
			return false;
		DId other = (DId) obj;
		if (_Id == null)
		{
			if (other._Id != null)
				return false;
		}
		else if (!_Id.equals(other._Id))
			return false;
		return true;
	}

	// = 日志接口(ILog)的实现 ============

	@Override
	public void logDebug(final Object message)
	{
		LogHelper.logDebug(this, message);
	}

	@Override
	public void logDebug(final Object message, final Throwable t)
	{
		LogHelper.logDebug(this, message, t);
	}

	@Override
	public void logError(final Object message)
	{
		LogHelper.logError(this, message);
	}

	@Override
	public void logError(final Object message, final Throwable t)
	{
		LogHelper.logError(this, message, t);
	}

	@Override
	public void logInfo(final Object message)
	{
		LogHelper.logInfo(this, message);
	}

	@Override
	public void logInfo(final Object message, final Throwable t)
	{
		LogHelper.logInfo(this, message, t);
	}

	@Override
	public void logWarn(final Object message)
	{
		LogHelper.logWarn(this, message);
	}

	@Override
	public void logWarn(final Object message, final Throwable t)
	{
		LogHelper.logWarn(this, message, t);
	}

}
